import React, {createElement} from 'react';
import {Spin} from 'antd';
import pathToRegexp from 'path-to-regexp';
import Loadable from 'react-loadable';
import {getMenuData} from './menu';

let routerDataCache;

const getRouterDataCache = app => {
  if (!routerDataCache) {
    routerDataCache = getRouterData(app);
  }
  return routerDataCache;
};

const modelNotExisted = (app, model) =>
  // eslint-disable-next-line
  !app._models.some(({namespace}) => {
    return namespace === model.substring(model.lastIndexOf('/') + 1);
  });

// wrapper of dynamic
const dynamicWrapper = (app, models, component) => {
  // register models
  models.forEach(model => {
    if (modelNotExisted(app, model)) {
      app.model(require(`../models/${model}`).default);
    }
  });

  // () => require('module')
  // transformed by babel-plugin-dynamic-import-node-sync
  if (component.toString().indexOf('.then(') < 0) {
    return props => {
      return createElement(component().default, {
        ...props,
        routerData: getRouterDataCache(app)
      });
    };
  }
  // () => import('module')
  return Loadable({
    loader: () => {
      return component().then(raw => {
        const Component = raw.default || raw;
        return props =>
          createElement(Component, {
            ...props,
            routerData: getRouterDataCache(app)
          });
      });
    },
    loading: () => {
      return <Spin size="large" className="global-spin"/>;
    }
  });
};

function getFlatMenuData(menus) {
  let keys = {};
  menus.forEach(item => {
    if (item.children) {
      keys[item.path] = {...item};
      keys = {...keys, ...getFlatMenuData(item.children)};
    } else {
      keys[item.path] = {...item};
    }
  });
  return keys;
}

function findMenuKey(menuData, path) {
  const menuKey = Object.keys(menuData).find(key => pathToRegexp(path).test(key));
  if (menuKey == null) {
    if (path === '/') {
      return null;
    }
    const lastIdx = path.lastIndexOf('/');
    if (lastIdx < 0) {
      return null;
    }
    if (lastIdx === 0) {
      return findMenuKey(menuData, '/');
    }
    // 如果没有，使用上一层的配置
    return findMenuKey(menuData, path.substr(0, lastIdx));
  }
  return menuKey;
}

export const getRouterData = app => {
  const routerConfig = {
    '/': {
      component: dynamicWrapper(app, ['user'], () => import('../layouts/BasicLayout'))
    },
    '/user': {
      component: dynamicWrapper(app, [], () => import('../layouts/UserLayout'))
    },
    '/user/login': {
      component: dynamicWrapper(app, ['user'], () => import('../routes/User/LoginPage'))
    },
    // '/user/register': {
    //   component: dynamicWrapper(app, ['user'], () => import('../routes/User/Register')),
    // },

    '/desktop': {
      component: dynamicWrapper(app, ['global', 'store', 'work', 'user'], () => import('../routes/desktop/Index'))
    },

    '/organization/tree': {
      component: dynamicWrapper(app, ['global', 'treeNode', 'user', 'organization'], () => import('../routes/organization/Index'))
    },


    '/tenant': {
      component: dynamicWrapper(app, ['global', 'tenant'], () => import('../routes/tenant/TenantMgr'))
    },
    '/work/index': {
      component: dynamicWrapper(app, ['global', 'work', 'user'], () => import('../routes/work/Index'))
    },
    //订单

    // '/sales/index': {
    //   component: dynamicWrapper(app, ['global', 'tenant','dynamicLabel'], () => import('../routes/sales/Bid')),
    // },
    //物料管理
    '/store/material': {
      component: dynamicWrapper(app, ['global', 'material', 'tenant', 'treeNode', 'dynamicLabel'], () => import('../routes/store/material'))
    },
    '/store/inbound': {
      component: dynamicWrapper(app, ['global', 'material', 'tenant', 'store', 'dynamicLabel'], () => import('../routes/store/InboundOrder'))
    },
    '/store/outbound': {
      component: dynamicWrapper(app, ['global', 'material', 'tenant', 'store', 'sales'], () => import('../routes/store/OutboundOrder'))
    },
    '/store/index': {
      component: dynamicWrapper(app, ['global', 'material', 'tenant', 'store', 'dynamicLabel'], () => import('../routes/store/Assess'))
    },
    //采购管理
    '/procure/vendor': {
      component: dynamicWrapper(app, ['global', 'vendor', 'tenant', 'dynamicLabel'], () => import('../routes/vendor/Index'))
    },
    '/procure/index': {
      component: dynamicWrapper(app, ['global', 'procure', 'tenant', 'vendor', 'dict'], () => import('../routes/procure/Index'))
    },
    '/procure/rent': {
      component: dynamicWrapper(app, ['global', 'procure', 'tenant', 'vendor', 'dict'], () => import('../routes/procure/Rent'))
    },
    '/procure/returnOfGoods': {
      component: dynamicWrapper(app, ['global', 'procure', 'tenant', 'vendor', 'dict'], () => import('../routes/procure/ReturnAndReplenishment'))
    },
    '/procure/acceptance': {
      component: dynamicWrapper(app, ['global', 'procure', 'tenant', 'vendor', 'dict'], () => import('../routes/procure/Acceptance'))
    },
    '/procure/review': {
      component: dynamicWrapper(app, ['global', 'procure', 'tenant', 'vendor', 'dict'], () => import('../routes/procure/Review'))
    },
    '/procure/assess': {
      component: dynamicWrapper(app, ['global', 'procure', 'tenant', 'vendor', 'dict'], () => import('../routes/procure/Assess'))
    },
    // '/procure/vendorAssess': {
    //   component: dynamicWrapper(app, ['global', 'procure', 'tenant', 'vendor', 'dict'], () => import('../routes/procure/VendorAssess'))
    // },
    //销售管理
    '/sales/customer': {
      component: dynamicWrapper(app, ['global', 'sales', 'tenant', 'customer', 'dynamicLabel'], () => import('../routes/customer/Index'))
    },
    '/sales/index': {
      component: dynamicWrapper(app, ['global', 'sales', 'tenant', 'store', 'finance'], () => import('../routes/sales/Index'))
    },
    '/sales/review': {
      component: dynamicWrapper(app, ['global', 'sales', 'tenant', 'store', 'finance'], () => import('../routes/sales/Review'))
    },
    '/sales/returnOfGoods': {
      component: dynamicWrapper(app, ['global', 'procure', 'tenant', 'vendor', 'dict'], () => import('../routes/sales/ReturnOfGoods'))
    },
    '/sales/statistics': {
      component: dynamicWrapper(app, ['global', 'sales', 'tenant'], () => import('../routes/sales/Assess'))
    },
    '/sales/rent': {
      component: dynamicWrapper(app, ['global', 'sales', 'tenant','finance', 'store'], () => import('../routes/sales/Rent'))
    },
    // 财务管理
    // '/finance/payable': {
    //   component: dynamicWrapper(app, ['global', 'procure', 'tenant', 'finance', 'dynamicLabel'], () => import('../routes/finance/Payable')),
    // },

    //销售管理
    '/salesMgr/bid': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/dic/Bid'))
    },
    '/salesMgr/account': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/dic/Account'))
    },
    '/salesMgr/customer': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/dic/Customer'))
    },

    //文档管理
    '/dic': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/dic/Index'))
    },
    '/dic/sample': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/experiment/Sample'))
    },
    //人事管理
    '/personnel/index': {
      component: dynamicWrapper(app, ['global','personnel', 'treeNode', ], () => import('../routes/personnel/Index'))
    },
    '/personnel/tree': {
      component: dynamicWrapper(app, ['global','personnel', 'treeNode', ], () => import('../routes/personnel/Tree'))
    },
    // '/personnel/pic': {
    //   component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/personnel/DayPersonnel'))
    // },
    // '/personnel/dict': {
    //   component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/personnel/PersonnelDic'))
    // },
    '/experiment/list': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/experiment/Index'))
    },
    '/experiment/simple': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/experiment/Sample'))
    },
    '/experiment/store': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'experiment'], () => import('../routes/experiment/Store'))
    },
    // '/experiment/day': {
    //   component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/dic/DayExperiment'))
    // },
    // '/finance/reimburse': {
    //   component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/finance/Reimburse'))
    // },
    '/finance/invoicing': {
      component: dynamicWrapper(app, ['global', 'tenant', 'customer','dict', 'finance'], () => import('../routes/finance/Invoicing'))
    },
    '/finance/invoicingReceipt': {
      component: dynamicWrapper(app, ['global', 'tenant', 'customer','dict', 'finance'], () => import('../routes/finance/InvoicingReceipt'))
    },
    '/finance/payApply': {
      component: dynamicWrapper(app, ['global', 'tenant', 'vendor','dict', 'procure'], () => import('../routes/finance/PaymentApplyForTree'))
    },
    '/finance/payReview': {
      component: dynamicWrapper(app, ['global', 'tenant', 'vendor','dict', 'procure'], () => import('../routes/finance/PaymentReviewTree'))
    },
    // '/finance/payment': {
    //   component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/finance/Payment'))
    // },
    '/finance/receipt': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/finance/ReceiptTree'))
    },
    // '/finance/receiptPayment': {
    //   component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/finance/ReceiptPayment'))
    // },
    '/finance/accountMgr': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'finance', 'dynamicLabel'], () => import('../routes/finance/AccountMgr'))
    },
    '/finance/assess': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'finance', 'store'], () => import('../routes/finance/Assess'))
    },

    '/day/personnel': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dic', 'dynamicLabel'], () => import('../routes/personnel/DayPersonnel'))
    },
    //系统配置
    '/settings/tableMgr': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dynamicLabel'], () => import('../routes/settings/LabelConfig'))
    },
    '/settings/employee': {
      component: dynamicWrapper(app, ['global', 'user'], () => import('../routes/employee/Index'))
    },
    '/settings/role': {
      component: dynamicWrapper(app, ['global', 'role', 'user'], () => import('../routes/employee/Role'))
    },
    '/settings/dict': {
      component: dynamicWrapper(app, ['global', 'dict', 'user'], () => import('../routes/settings/DictMgr'))
    },
    '/settings/test': {
      component: dynamicWrapper(app, ['global', 'tenant', 'dynamicLabel'], () => import('../routes/settings/Test'))
    }
  };
  // Get name from ./menu.js or just set it in the router data.
  const menuData = getFlatMenuData(getMenuData());

  // Route configuration data
  // eg. {name,authority ...routerConfig }
  const routerData = {};
  // The route matches the menu
  Object.keys(routerConfig).forEach(path => {
    // Regular match item name
    // eg.  router /user/:id === /user/chen

    let menuKey = Object.keys(menuData).find(key => pathToRegexp(path).test(`${key}`));

    const inherited = menuKey == null;
    if (menuKey == null) {
      menuKey = findMenuKey(menuData, path);
    }
    let menuItem = {};
    // If menuKey is not empty
    if (menuKey) {
      menuItem = menuData[menuKey];
    }
    let router = routerConfig[path];
    // If you need to configure complex parameter routing,
    // https://github.com/ant-design/ant-design-pro-site/blob/master/docs/router-and-nav.md#%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E8%B7%AF%E7%94%B1%E8%8F%9C%E5%8D%95
    // eg . /list/:type/user/info/:id
    router = {
      ...router,
      name: router.name || menuItem.name,
      authority: router.authority || menuItem.authority,
      hideInBreadcrumb: router.hideInBreadcrumb || menuItem.hideInBreadcrumb,
      inherited
    };
    routerData[path] = router;
  });
  return routerData;
};
